// respawn.txt
// Like basicnpc.txt, but is part of a group and respawns a group member
// when killed once too many of that group have been killed.
// Memory Cells:
//   Cell 0 - How creature moves.
//     0 - If 0, wander randomly. 
//     1 - Stands still until a target appears.
//     2 - Completely immobile, even if target appears.
//   Cell 1,2 - Stuff done flag. If the creature is killed, increments this 
//     by 1.  (see basicnpc.txt for example on how this works in more detail)
//   Cell 3 - Dialogue node to start with if talked to. if left at 0, this
//     character doesn't talk.
//   Cell 4 - Number of group to place creature in.
//   Cell 5 - Percentage of group that can be killed off before respwaning
//     occurs.  Must be a number between 0 and 100.
//
// NOTE: For most efficient use, group the members of the group specified
//  in Memory Cell 4 close together.

begincreaturescript;

variables;

short i,j,target;
short respawn;
short group_stats, num_char, lowest_char, highest_char;
short first_char, updown;


body;

beginstate INIT_STATE;

group_stats = 0;
set_script_mode(3);

// Sets mobility
if (get_memory_cell(0) == 2)
	set_mobility(ME,0);

// Adds NPC to group specified in Memory Cell 4.

if (get_memory_cell(4) != 0)
 add_char_to_group(ME,get_memory_cell(4));

break;


beginstate DEAD_STATE;

// Increments group death counter specified in Memory Cell 1 and 2.
inc_flag(get_memory_cell(1),get_memory_cell(2),1);

// If the percentage specified in Memory Cell 5 of the characters in the group
// specified in Memory Cell 4 has been killed, will attempt to spawn a member
// of that group.  The script checks to ensure spawning only occurs far from 
respawn = 0;
if (get_sdf(get_memory_cell(1),get_memory_cell(2)) >= ((get_memory_cell(5)*num_char)/100)) {
 first_char = get_ran(1,lowest_char,highest_char);
 updown = get_ran(1,0,1);
 i = first_char;
 while ((respawn == 0) && (j <= num_char)) {
  if ((char_ok(i) == 0) && (char_in_group(i,get_memory_cell(4))) && (i != my_number())) {
   spawn_creature(i);
   respawn = 1;
   inc_flag(get_memory_cell(1),get_memory_cell(2),-1);
   if (group_dist_to_loc(0,char_loc_x(i),char_loc_y(i)) <= 8) {
    erase_char(i);
    respawn = 0;
    inc_flag(get_memory_cell(1),get_memory_cell(2),1);
   }
  }
  j = j + 1;
  if (updown == 0)
   i = i + 1;
  else
   i = i - 1;
  if (i > highest_char) {
   i = first_char - 1;
   updown = 1;
  }
  if (i < lowest_char) {
   i = first_char + 1;
   updown = 0;   
  }
 }
}

break;


beginstate START_STATE; 

// Develops information on group specified in Memory Cell 4.
if (group_stats == 0) {
 i = 6;
 lowest_char = 0;
 highest_char = 0;
 num_char = 0;
 while (i <= 120) {
  if (char_in_group(i,get_memory_cell(4)) == 1) {
   num_char = num_char + 1;
   highest_char = i;
   if (lowest_char == 0)
    lowest_char = i;
  }
  i = i +1;
 }
 group_stats = 1;
}   

	// if I have a target for some reason, go attack it
	if (target_ok()) {
		if (dist_to_char(get_target()) <= 16)
			set_state(3);
			else set_target(ME,-1);
		}
	
	// Look for a target, attack it if visible
	if (select_target(ME,8,0)) {
		do_attack();
		set_state(3);
		}
		
	// Have I been hit? Strike back!
	if (who_hit_me() >= 0) {
		set_target(ME,who_hit_me());
		do_attack();
		set_state(3);
		}
		
	// Otherwise, just peacefully move around. Go back to start, if I'm too far
	// from where I started.
	if ((my_dist_from_start() >= 6) || ((my_dist_from_start() > 0) && (get_memory_cell(0) > 0))) {
		if (get_ran(1,1,100) < 40) 
			return_to_start(ME,1);
		}
		else if (get_memory_cell(0) == 0) {
			fidget(ME,25);
			}

	// if we're in combat and the above didn't give me anything to do, just
	// stop now. Otherwise, game will keep running script, and that eats up CPU time.
	if (am_i_doing_action() == FALSE)
		end_combat_turn();
break;

beginstate 3; // attacking
	if (target_ok() == FALSE)
		set_state(START_STATE);
	do_attack();
break;

beginstate TALKING_STATE;
	if (get_memory_cell(3) == 0) {
		print_str("Talking: It doesn't respond.");
		end();
		}
	begin_talk_mode(get_memory_cell(3));
break;